package com.cskaoyan.javase.reflect._3constructor;

import com.cskaoyan.javase.reflect.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * Constructor类表示构造器
 *
 * Java当中创建对象的方式:
 *      1.new对象
 *      2.clone
 *      3.序列化反序列化
 *      4.反射(实际开发中最常用的,但是隐藏在框架底层,程序员不需要操作)
 *
 * @since 10:47
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // 以下方法都是Class类API
        // 获取Person类的Class
        Class<?> perClazz = Class.forName("com.cskaoyan.javase.reflect.Person");

        // 获取多个Constructor
        // 获取所有的public修饰的构造方法
        // Constructor[] getConstructors()
        Constructor<?>[] publicCons = perClazz.getConstructors();
        for (Constructor<?> publicCon : publicCons) {
            System.out.println(publicCon);
        }

        System.out.println("----------------");
        // 获取所有的构造方法(包含私有的)
        // Constructor[] getDeclaredConstructors()
        Constructor<?>[] declaredConstructors = perClazz.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
        System.out.println("--------------");

        // 获取public修饰的, 指定参数类型所对应的构造方法
        // Constructor<T> getConstructor(Class<?>... parameterTypes)
        Constructor<?> c1 = perClazz.getConstructor(int.class, String.class);
        System.out.println(c1);
        System.out.println("--------------------");
        // System.out.println(perClazz.getConstructor(String.class));
        // 获取指定参数类型所对应的构造方法(包含私有的)
        // Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
        System.out.println(perClazz.getDeclaredConstructor(String.class));
        // 不填实参,就是获取无参构造器
        System.out.println(perClazz.getDeclaredConstructor());

        // Constructor类当中有以下成员方法,用于new对象给成员变量赋值
        // 传入相应参数，在创建对象过程中赋值，返回值是一个相应对象
        // T newInstance(Object... initargs)
        Constructor<?> personC1 = perClazz.getConstructor(int.class, String.class, String.class);
        Object p = personC1.newInstance(18, "张三", "男");
        System.out.println(((Person) p));
    }
}
